/**
* All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
*
* SdProjectPlanService
* 项目策划
*
* 修改纪录
* 2021-12-20版本：1.0 hdy 创建。
* @version 版本：1.0
* @author 作者：hdy
* 创建日期：2021-12-20
*/
package com.topscomm.gpm.service.impl;

import com.topscomm.basic.exception.MessageException;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.gpm.GpmSystemConst;
import com.topscomm.gpm.pojo.*;
import com.topscomm.mis.constant.MisSystemConst;
import com.topscomm.mis.mobile.message.service.SendMessageService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.DateUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.SessionUserBean;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.topscomm.gpm.service.IGpmProjectPlanService;
import com.topscomm.gpm.service.impl.auto.GpmProjectPlanServiceAuto;
import com.topscomm.base.BaseSystemConst;
import com.topscomm.base.pojo.BaseChangeLogEntity;
import com.topscomm.base.service.impl.BaseChangeLogService;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.pojo.CboApprovalNodeEntity;
import com.topscomm.cbo.pojo.CboApprovalNodeInsEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.cbo.service.impl.CboApprovalNodeInsService;
import com.topscomm.cbo.service.impl.CboUserService;
import com.topscomm.gpm.pojo.GpmProjectEntity;
import com.topscomm.gpm.pojo.GpmProjectMilepostEntity;
import com.topscomm.gpm.pojo.GpmProjectPlanEntity;
import com.topscomm.gpm.pojo.GpmProjectTaskEntity;
import com.topscomm.gpm.pojo.GpmProjectTaskFeedbackEntity;
import com.topscomm.gpm.pojo.GpmProjectAppointmentEntity;

@Service(value = "gpmProjectPlanService")
@Scope(value = "singleton")
public class GpmProjectPlanService extends GpmProjectPlanServiceAuto implements IGpmProjectPlanService {
	FlowDatacodeCache flowDatacodeCache=new FlowDatacodeCache();
	protected List<Map<String,Object>> flowidList=new ArrayList();

	@Autowired
	private GpmProjectService gpmProjectService;
	@Autowired
	private GpmProjectMilepostService gpmProjectMilepostService;
	@Autowired
	private GpmProjectTaskService gpmProjectTaskService;
//	@Autowired
//	private ICboMessageAppService cboMessageAppService;
//	@Autowired
//	private ICboMessageSysService cboMessageSysService;
    @Autowired
    private BaseChangeLogService baseChangeLogService;
    @Autowired
    private GpmProjectUniversalChangeService gpmProjectUniversalChangeService;
	@Autowired
	private GpmProjectPlanService gpmProjectPlanService;
	@Autowired
	private GpmProjectAppointmentService gpmProjectAppointmentService;
	@Autowired
	private CboApprovalNodeInsService cboApprovalNodeInsService;
	@Autowired
	private CboUserService cboUserService;

	@Autowired
	private SendMessageService sendMessageService;
	/**
	 * @author: hdy
	 * @date: 2021-01-07
	 * @param entity
	 * @throws ServiceException
	 * @description:单号生成
	 * @modify:
	 */
	@Override
	protected void beforeInsert(BasicEntity entity) throws ServiceException{
		super.beforeInsert(entity);

		if (entity.getId() <= 0) {// 赋值Id和单号
			long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
			entity.setId(arrayId[0]);
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle("enabled =1 and state=9 and projectcode = '{0}'",entity.getValue("projectcode"));
			List<GpmProjectPlanEntity> entites = this
				.queryByWhere(sql.toString());
			if(entites.size()<1){
				entity.setValue("version",1);
			}else{
				long a = entites.get(0).getVersion();
				a++;
				entity.setValue("version",a);
			}
			String docNo = String.valueOf(arrayId[0]);
			docNo = docNo.substring(0, 6) + docNo.substring(9);
			entity.setValue(GpmProjectPlanEntity.FieldDocno, docNo);
			 GpmProjectPlanEntity gpmProjectPlanEntity = (GpmProjectPlanEntity) entity;
			//赋值策划编号
			String proposalcode = this.generateProposalcode(gpmProjectPlanEntity);
			entity.setValue(GpmProjectPlanEntity.FieldProposalcode, proposalcode);
		}
	}

    @Override
    protected void afterInsert(BasicEntity entity) throws ServiceException {
        super.afterInsert(entity);
        GpmProjectPlanEntity projectPlanEntity = (GpmProjectPlanEntity) entity;
        StringBufferProxy whereSql = new StringBufferProxy();
        whereSql.appendSingle(" {0} = '{1}' and state = '9' ", GpmProjectPlanEntity.FieldProjectcode,
                projectPlanEntity.getProjectcode());
        if(this.getCount(whereSql.toString()) > 0) {
            this.insertUniversalChange(projectPlanEntity);
        }
    }

    @Override
	protected void updateAfter(Map<String, Object> map) throws ServiceException {
		super.updateAfter(map);
		//更新变更模块的变更原因字段
		Map<String,Object> changeUpdateMap = new HashMap<String,Object>();
		changeUpdateMap.put(GpmProjectUniversalChangeEntity.FieldChangereason, map.get("changereason"));
		gpmProjectUniversalChangeService.updateByWhere(changeUpdateMap,"sourceid="+map.get("id") + " and sourcetype='"+ GpmProjectPlanEntity.tableName +"' and version="
				+map.get("version"));
	}

    private void insertUniversalChange(GpmProjectPlanEntity projectPlanEntity) {
        GpmProjectEntity projectEntity = gpmProjectService.queryById(ConvertUtil.convertToString(projectPlanEntity.getProjectid()));
        GpmProjectUniversalChangeEntity universalChangeEntity = new GpmProjectUniversalChangeEntity();
        universalChangeEntity.setProjectname(projectEntity.getProjectname());
        universalChangeEntity.setProjectid(projectEntity.getId());
        universalChangeEntity.setProjectcode(projectEntity.getProjectcode());
        universalChangeEntity.setSourcetype(GpmProjectPlanEntity.tableName);
        universalChangeEntity.setSourceid(projectPlanEntity.getId());
        universalChangeEntity.setProjectmanager(projectEntity.getProjectmanager());
        universalChangeEntity.setProjectmanagercode(projectEntity.getProjectmanagercode());
        universalChangeEntity.setChangereason(projectPlanEntity.getChangereason());
        universalChangeEntity.setDeptname(getSessionUserBean().getDept().getFullname());
        universalChangeEntity.setDeptcode(getSessionUserBean().getDept().getCode());
        universalChangeEntity.setUsername(getSessionUserBean().getUser().getName());
        universalChangeEntity.setUsercode(getSessionUserBean().getUser().getCode());
        universalChangeEntity.setDocdate(new Date());
        universalChangeEntity.setVersion(projectPlanEntity.getVersion());

        gpmProjectUniversalChangeService.insert(universalChangeEntity);
    }

	/***
	 * @description: 生成策划编号
	 * @param gpmProjectPlanEntity
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/1 14:51
	 * @modify:
	 */
	private String generateProposalcode(GpmProjectPlanEntity gpmProjectPlanEntity) {
		StringBuffer proposalcode = new StringBuffer();
		// 前两位
		proposalcode.append("CH");
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("projectcode = '{0}'", gpmProjectPlanEntity.getProjectcode());
		GpmProjectEntity gpmProjectEntity = gpmProjectService.queryObjectByWhere(sql.toString());
		if (gpmProjectEntity == null) {
			throw new ServiceException("该策划没有对应的通用信息，请核对！");
		}
		String projectlevel = gpmProjectEntity.getProjectlevel();
		String[] array = { "A", "B", "C", "D" };
		projectlevel = array[ConvertUtil.convertToInt(projectlevel)];
		// 第三位
		proposalcode.append(projectlevel);
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyMMdd");
		String datacode = sdFormat.format(new Date());
		// 第4-7位
		proposalcode.append(datacode, 0, 4);
		// 第8-10位
		if (StringUtil.isEmpty(gpmProjectPlanEntity.getProposalcode())) {
			sql.clear();
			sql.appendSingle(" length({0}) = 10", GpmProjectPlanEntity.FieldProposalcode);
			List<Map<String, Object>> proposalcodelist = gpmProjectPlanService.queryMapForPage(sql.toString(), 1, 10, "createon", "desc");
			if (proposalcodelist.size() == 0) {
				proposalcode.append("001");
			} else {
				String lastproposalcode = ConvertUtil.convertToString(proposalcodelist.get(0).get("proposalcode"));
				String lastmonth = lastproposalcode.substring(5, 7);
				if (datacode.substring(2, 4).equals(lastmonth)) {
					DecimalFormat decimalFormat = new DecimalFormat("000");
					String substring1 = lastproposalcode.substring(7);
					int i = Integer.parseInt(substring1) + 1;
					proposalcode.append(decimalFormat.format(i));
				} else {
					proposalcode.append("001");
				}
			}
		} else {
			proposalcode.append("001");
		}
		return proposalcode.toString();
	}

	@Override
	protected void beforeSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
		super.beforeSubmit(entity, sessionUserBean);
		GpmProjectPlanEntity gpmProjectPlanEntity = (GpmProjectPlanEntity) entity;
		// 策划提交审批时，检测任命是否已审核完毕，如果任命未审核完毕，不允许策划提交审批
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("projectid = '{0}' and state = 9 and enabled = 1", gpmProjectPlanEntity.getProjectid());
		List<GpmProjectAppointmentEntity> gpmProjectAppointmentEntityList = gpmProjectAppointmentService.queryByWhere(sql.toString());
		if(gpmProjectAppointmentEntityList.size() == 0) {
			throw new MessageException("任命未审批完成，请在任命审批完成后再提交审批！");
		}
		// 审批流程赋值
		this.flowidList = flowDatacodeCache
				.getApprovalFlowListMap("ApprovalFlow_GpmProjectPlan",
						gpmProjectPlanEntity.getApplyusercode(), "sortcode");
		if (flowidList.size() > 0) {
			gpmProjectPlanEntity.setFlowid(ConvertUtil.convertToLong(flowidList.get(0).get("id")));
		} else {
			throw new ServiceException("没有匹配的审批流，请联系管理员！");
		}
		long planid = gpmProjectPlanEntity.getId();
		sql.clear();
		sql.appendSingle("planid = '{0}' and enabled= 0 order by planfinishtime,id asc", planid);
		List<GpmProjectMilepostEntity> gpmProjectMilepostEntityList = gpmProjectMilepostService.queryByWhere(sql.toString());
		if (gpmProjectMilepostEntityList.size() == 0) {
			throw new MessageException("未添加里程碑，添加里程碑后再提交审批！");
		}
		String projectcode = gpmProjectPlanEntity.getProjectcode();
		sql.clear();
		//里程碑所属项目的计划结束时间
		sql.appendSingle("projectcode = '{0}'", projectcode);
		GpmProjectEntity gpmProjectEntity = gpmProjectService.queryObjectByWhere(sql.toString());
		Date projectplanenddate = gpmProjectEntity.getPlanenddate();
		for (GpmProjectMilepostEntity t : gpmProjectMilepostEntityList) {
			if (t.getPlanfinishtime() == null) {
				throw new MessageException("请完善里程碑信息！");
			}
			if (t.getPlanfinishtime().compareTo(projectplanenddate) > 0) {
				throw new MessageException("里程碑的计划达成时间不能大于所属通用项目的计划结束时间！");
			}
		}
	}

	/**
	 * @description: 提交审批后
	 * @param entity
	 * @param sessionUserBean
	 * @return void
	 * @author: wangxinhua
	 * @date: 2021/12/16 14:15
	 * @modify:
	 */
	@Override
	protected void afterSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
		//生成变更记录
		GpmProjectPlanEntity gpmProjectPlanEntity = (GpmProjectPlanEntity)entity;
		if(gpmProjectPlanEntity.getVersion() > 1) {
			Map<String,Object> appointmentMap = gpmProjectPlanEntity.convertToMap();
			try {
				//删除上次的basechangelog
				baseChangeLogService.deleteByWhere(" topsourcetype='"+ gpmProjectPlanEntity.getTableName()+"'"
						+ " and topsourceid='"+ gpmProjectPlanEntity.getId()+"'"
						+ " and version="+ gpmProjectPlanEntity.getVersion() +" and sourcetype !='GpmProjectTask'");
				Map<String, Object> changeData = this.getBaseChangeEntity(appointmentMap);
				saveBaseChangelog(changeData, ConvertUtil.convertToString(gpmProjectPlanEntity.getId()), false);
			} catch (Exception e) {
				throw new ServiceException(e.getMessage());
			}
		}
		try {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendLineSingle("update CboApprovalFlowIns set ");
			sql.appendLineSingle("extendfield1 = {0},extendfield2 ='{1}',extendfield3='{2}'",
					gpmProjectPlanEntity.getDocno(), gpmProjectPlanEntity.getDeptcode(), gpmProjectPlanEntity.getUsercode());
			sql.appendLineSingle("where sourceid = '{0}' and sourcetype='{1}'", entity.getId(), entity.getTableName());

			this.getDao().updateExecute(sql.toString());
			this.updateUniversalChange(entity, new Date(), GpmProjectPlanEntity.tableName);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		super.afterSubmit(entity, sessionUserBean);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	protected void deleteBefore(String whereSql) {
		super.deleteBefore(whereSql);
		//找到这条策划
		List<GpmProjectPlanEntity> sdProjectPlanEntities = this.queryByWhere(whereSql);
		if (sdProjectPlanEntities.size() == 0) {
			return;
		}
		String planid = ConvertUtil.convertToString(sdProjectPlanEntities.get(0).getId());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date plandate = sdProjectPlanEntities.get(0).getCreateon();
		String createdate = sdf.format(plandate);
		String projectcode = sdProjectPlanEntities.get(0).getProjectcode();
		// 删除对应的任务，由于任务可能挂到不同的策划上，因此只可以删除创建时间之后的任务
		StringBufferProxy delsql = new StringBufferProxy();
		delsql.appendSingle("projectcode = '{0}' and createon >= {1} ", projectcode, SQLAdapter.toDateLong(createdate));
		gpmProjectTaskService.deleteByWhere(delsql.toString());
		//删除里程碑
		delsql.clear();
		delsql.appendSingle(" planid = '{0}'", planid);
		gpmProjectMilepostService.deleteByWhere(delsql.toString());
		delsql.clear();
		delsql.appendSingle(" delete from {2} where sourceid in (select id from {0} where {1} ) and sourcetype= '{0}' ", GpmProjectPlanEntity.tableName,whereSql, GpmProjectUniversalChangeEntity.tableName);
		gpmProjectUniversalChangeService.deleteExecute(delsql.toString());
	}

	/**
	 * @param billEntity
	 * @param nodeIns
	 * @author: zhangsui
	 * @date: 2016年8月8日下午2:26:58
	 * @return_type: void
	 * @description: 审批后处理
	 * @modify:
	 */
	@Override
	protected void afterApprove(TapEntity billEntity, CboApprovalNodeInsEntity nodeIns, CboApprovalNodeEntity node,
			SessionUserBean sessionUserBean) {
		this.updateUniversalChange(billEntity, GpmProjectPlanEntity.tableName);
		super.afterApprove(billEntity, nodeIns, node, sessionUserBean);
	}

	/***
	 * @description: 发送策划App通知消息
	 * @param gpmProjectPlanEntity
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/1 14:46
	 * @modify:
	 */
	private void sendMessageAppAndSys(GpmProjectPlanEntity gpmProjectPlanEntity) {
		GpmProjectEntity gpmProjectEntity = gpmProjectService.queryById(ConvertUtil.convertToString(gpmProjectPlanEntity.getProjectid()));
		String sdId = ConvertUtil.convertToString(gpmProjectEntity.getId());
		StringBufferProxy content = new StringBufferProxy();
		Map<String, Object> messageAppmap = new HashMap<String, Object>();
		content.appendSingle("您提交的【{0}】策划书已审批通过，策划书编号为{1}，请于2天内组织召开项目开工会",
				gpmProjectPlanEntity.getProjectname(), gpmProjectPlanEntity.getProposalcode());
//		messageAppmap.put("usercode", gpmProjectPlanEntity.getUsercode());
		messageAppmap.put("content", content.toString());
		messageAppmap.put("extendfield1", "策划审批通知");
		messageAppmap.put("sendtype", "0");
		messageAppmap.put("sourcetype", GpmProjectPlanEntity.tableName);
		messageAppmap.put("sourceid", sdId);
		messageAppmap.put("messagetype", MisSystemConst.MobileMessageType.OTHER_TYPE);
		messageAppmap.put("receivercode", gpmProjectEntity.getUsercode());
		messageAppmap.put("receivername", gpmProjectEntity.getUsername());
//		cboMessageAppService.insertMap(messageAppmap);
		sendMessageService.sendAppMessage(messageAppmap);
		// 系统通知消息
		Map<String, Object> messageSysAppmap = new HashMap<String, Object>();
		messageSysAppmap.put("receivercode", gpmProjectPlanEntity.getUsercode());
		messageSysAppmap.put("receivername", gpmProjectPlanEntity.getUsername());
		messageSysAppmap.put("content", content.toString());
		messageSysAppmap.put("subject", "策划审批通知");
		messageSysAppmap.put("ishtm", "0");
		messageSysAppmap.put("sourcetype", GpmProjectPlanEntity.tableName);
		messageSysAppmap.put("sourceid", sdId);
		messageSysAppmap.put("messagetype", MisSystemConst.MobileMessageType.OTHER_TYPE);
//		cboMessageSysService.insertMap(messageSysAppmap);
		sendMessageService.sendSysMessage(messageSysAppmap);
	}

    @Override
    protected void afterDelApprove(TapEntity entity, SessionUserBean sessionUserBean) {
        //取消审批删除通用变更表信息
        gpmProjectUniversalChangeService.deleteByWhere("sourceid = " + entity.getValue("id") +
                " and sourcetype = '" + GpmProjectPlanEntity.tableName + "' and version = "+entity.getValue("version"));
		super.afterDelApprove(entity, sessionUserBean);
    }
	/**
     * @description: 获取变更内容实体类
     * @param inputMap
     * @return Map<String,Object>
     * @author: wangxinhua
     * @date: 2021/12/17 16:13
     * @modify:
     */
    private Map<String, Object> getBaseChangeEntity(Map<String, Object> inputMap) throws Exception {
        long projectId = ConvertUtil.convertToLong(inputMap.get("projectid"));

        // 获取之前版本主表数据
        Map<String, Object> historyData = this.queryMapByWhere(" projectid=" + projectId + " order by version desc").get(1);
        // 所有变更数据返回
        Map<String, Object> resMap = new HashMap<String, Object>();

        // 组装主表要去对比的数据
        Map<String, Object> changeMap = new HashMap<String, Object>();
        changeMap.put("topsourcetype", GpmProjectPlanEntity.tableName);
        changeMap.put("topsourceid", ConvertUtil.convertToString(inputMap.get("id")));
        changeMap.put("sourcetype", GpmProjectPlanEntity.tableName);
        changeMap.put("sourceid", ConvertUtil.convertToString(inputMap.get("id")));
        changeMap.put("newmap", inputMap);
        changeMap.put("oldmap", historyData);
        changeMap.put("baselogoperatetype", BaseSystemConst.BaseLogOperateTypeEnum.Edit);
        changeMap.put("version", ConvertUtil.convertToString(inputMap.get("version")));
        BaseChangeLogEntity mainContent = this.getMainChangeLogEntity(changeMap);
        // 获取之前版本团队类别
        List<Map<String, Object>> milepostHistoryList = gpmProjectMilepostService.queryMapByWhere(" planid=" + historyData.get("id"));
        // 获取当前前版本团队类别
        List<Map<String, Object>> milepostList = gpmProjectMilepostService.queryMapByWhere(" planid=" + inputMap.get("id"));

        List<BasicEntity> milepostContent = this.getMilepostChangeEntity(milepostList, milepostHistoryList, inputMap);

        resMap.put("mainContent", mainContent);
        resMap.put("milepostContent", milepostContent);
        return resMap;
    }

    private List<BasicEntity> getMilepostChangeEntity(List<Map<String, Object>> teamTypeList, List<Map<String, Object>> teamTypeHistoryList, Map<String, Object> historyData) throws Exception {
        //所有变更的结果
        List<BasicEntity> resContent = new ArrayList<BasicEntity>();
        Map<String, Object> changeProductMap = new HashMap<String, Object>();
        changeProductMap.put("sourcetype", GpmProjectMilepostEntity.tableName);
        changeProductMap.put("topsourcetype", GpmProjectPlanEntity.tableName);
        changeProductMap.put("topsourceid", ConvertUtil.convertToString(historyData.get("id")));
        changeProductMap.put("version", ConvertUtil.convertToString(historyData.get("version")));
        List<String> noDelIds = new ArrayList<String>();
        for (Map<String, Object> newItem : teamTypeList) {
            if (newItem.containsKey("copysourceid") && !"0".equals(newItem.get("copysourceid").toString())) {
                boolean hasHistory = false;
                Map<String, Object> matchHistory = new HashMap<String, Object>();
                for (Map<String, Object> historyItem : teamTypeHistoryList) {
                    if (newItem.get("copysourceid").toString().equals(historyItem.get("id").toString())) {
                        hasHistory = true;
                        matchHistory = historyItem;
                    }
                }
                if (hasHistory) {
                    noDelIds.add(ConvertUtil.convertToString(matchHistory.get("id")));
                    changeProductMap.put("baselogoperatetype", BaseSystemConst.BaseLogOperateTypeEnum.Edit);
                    changeProductMap.put("newmap", newItem);
                    changeProductMap.put("oldmap", matchHistory);
                    changeProductMap.put("sourceid", newItem.get("id"));
                    BaseChangeLogEntity perContent = this.getMainChangeLogEntity(changeProductMap);
                    if(perContent != null){
                        resContent.add(perContent);
                    }
                }
            } else {
                changeProductMap.put("baselogoperatetype", BaseSystemConst.BaseLogOperateTypeEnum.Add);
                changeProductMap.put("newmap", newItem);
                changeProductMap.put("oldmap", newItem);
                changeProductMap.put("sourceid", newItem.get("id"));
                BaseChangeLogEntity perContent = this.getMainChangeLogEntity(changeProductMap);
                resContent.add(perContent);
            }
        }
        //查询删除的产品线
        if(noDelIds.size()>0){
            List<Map<String,Object>> delProducts = gpmProjectMilepostService.queryMapByWhere( " planid =" + teamTypeHistoryList.get(0).get("planid") + " and id not in (" + StringUtils.join(noDelIds, ",") + ")");
            for(Map<String,Object> delItem : delProducts){
                changeProductMap.put("baselogoperatetype", BaseSystemConst.BaseLogOperateTypeEnum.Del);
                changeProductMap.put("newmap", delItem);
                changeProductMap.put("oldmap", delItem);
                changeProductMap.put("sourceid", delItem.get("id"));
                BaseChangeLogEntity perContent = this.getMainChangeLogEntity(changeProductMap);
                resContent.add(perContent);
            }
        }
        return resContent;
    }

    /**
     * @description: 保存字段变更
     * @param changeData
     * @return void
     * @author: wangxinhua
     * @date: 2021/12/10 16:11
     * @modify:
     */
    public void saveBaseChangelog(Map<String, Object> changeData, String planId, Boolean ignoreNoChange) {
        BasicEntity mainContent = (BasicEntity)changeData.get("mainContent");
        List<BasicEntity> milepostContent = (List<BasicEntity>)changeData.get("milepostContent");
        if(mainContent == null && milepostContent.size()<=0 && !ignoreNoChange) {
            GpmProjectPlanEntity gpmProjectPlanEntity = this.queryById(planId);
            int count = baseChangeLogService.getCount(" topsourcetype='"+ GpmProjectPlanEntity.tableName+"'"
                    + " and topsourceid='"+planId+"'"
                    + " and version="+ gpmProjectPlanEntity.getVersion() +" and sourcetype='GpmProjectTask'");
            if(count<=0) {
                throw new ServiceException("无变更内容无法提交审批，请先更改数据！");
            }
        }
        if(mainContent != null){
            baseChangeLogService.insert(mainContent);
        }
        baseChangeLogService.insertBatch(milepostContent);
    }

    /**
     * @description: 变更退回修改节点审批通过
     * @param id
     * @return
     * @author: wangxinhua
     * @date: 2021/12/13 14:39
     * @modify:
     */
    @Transactional(rollbackFor = Exception.class)
    public void changeEditNodePass(String id) {
        GpmProjectPlanEntity planEntity = this.queryById(id);
        //删除上次的basechangelog
        baseChangeLogService.deleteByWhere(" topsourcetype='"+planEntity.getTableName()+"'"
                + " and topsourceid='"+planEntity.getId()+"'"
                + " and version="+planEntity.getVersion() +" and sourcetype !='GpmProjectTask'");
        try {
            Map<String, Object> changeData = this.getBaseChangeEntity(planEntity.convertToMap());
            this.saveBaseChangelog(changeData, id, true);
        }catch (Exception e) {
            throw new ServiceException("存储变更信息失败！");
        }
    }
	/**
	 * @return Map<String, Object>
	 * @author houyuhang
	 * @Description 首页信息概览策划待办
	 * @Date 2021/12/21
	 **/
	public Map<String, Object> queryBacklogPlan(Map<String, Object> paraMap) {
		Map<String, Object> backlogPlanResult = new HashMap<>();
		StringBufferProxy sql = new StringBufferProxy();
		// 项目状态为进行中的数据权限内项目
		sql.appendSingle(" GPMPROJECT.projectstate in ({0}) and GPMPROJECT.enabled = 1 and {1} ", GpmSystemConst.ProjectOngoingState,
				gpmProjectService.whereExistsSqlForIndex(GpmProjectEntity.tableName, GpmProjectEntity.FieldId,
						ConvertUtil.convertToString(paraMap.get("dataPermissionFlag"))));
		// 策划待办拼接字符串,项目任命签署时间不为空，但项目策划不存在或者只存在一条未提交审批的策划
		sql.appendSingle("AND gpmPROJECTAPPOINTMENT.VERSION = 1 AND gpmPROJECTAPPOINTMENT.SIGNDATE IS NOT NULL AND (GpmProjectPlan.ID IS NULL OR " +
				"(GpmProjectPlan.STATE = 0 AND GpmProjectPlan.VERSION = 1))");
		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put("whereSql", sql.toString());
		int countBacklogPlan = gpmProjectService.getCount(dataMap, "queryPlanOverdue");
		backlogPlanResult.put("code", "backlogPlanNum");
		backlogPlanResult.put("name", "策划待办");
		backlogPlanResult.put("iconImg", "/static/images/paojectManager/backlogPlan.png");
		backlogPlanResult.put("value", countBacklogPlan);
		return backlogPlanResult;
	}
	/**
	 * @return Map<String, Object>
	 * @author houyuhang
	 * @Description 首页策划超期
	 * @Date 2021/12/21
	 **/
	public Map<String, Object> queryOverduePlan(Map<String, Object> paraMap) {
		Map<String, Object> overduePlanResult = new HashMap<>();
		StringBufferProxy sql = new StringBufferProxy();
		// 项目状态为进行中的数据权限内项目，且任命签署时间早于今日之前的七个工作日
		sql.appendSingle(" GPMPROJECT.projectstate in ({0}) and GPMPROJECT.enabled = 1 and {1} ", GpmSystemConst.ProjectOngoingState,
				gpmProjectService.whereExistsSqlForIndex(GpmProjectEntity.tableName, GpmProjectEntity.FieldId,
						ConvertUtil.convertToString(paraMap.get("dataPermissionFlag"))));
		// 策划超期拼接字符串,项目任命签署时间不为空，但项目策划不存在或者只存在一条未审批完成的策划
		sql.appendSingle("AND gpmPROJECTAPPOINTMENT.VERSION = 1 AND gpmPROJECTAPPOINTMENT.SIGNDATE IS NOT NULL AND (GpmProjectPlan.ID IS NULL OR " +
				"(GpmProjectPlan.STATE < 9 AND GpmProjectPlan.VERSION = 1))");
		// 获取7天之前的日期
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		String overduePlanTime = GpmSystemConst.overduePlanTime;
		int time = Integer.parseInt(overduePlanTime) * (-1);
		calendar.add(Calendar.DATE,time);
		Date overdueDate = calendar.getTime();
		String overdueTime = DateUtil.dateToString(overdueDate,"yyyy-MM-dd");
		Map<String,Object> dataMap = new HashMap<>();
		dataMap.put("whereSql",sql.toString());
		dataMap.put("overdue",1);
		dataMap.put("overduetime",overdueTime);
		int countPlan = gpmProjectService.getCount(dataMap, "queryPlanOverdue");
		overduePlanResult.put("code", "overduePlanNum");
		overduePlanResult.put("name", "超期策划");
		overduePlanResult.put("iconImg", "/static/images/paojectManager/overduePlan.png");
		overduePlanResult.put("value", countPlan);
		return overduePlanResult;
	}

	/**
	 * @return void
	 * @author houyuhang
	 * @Description 将旧策划书有效性置为0，并把旧策划书下的里程碑有效性全部置为0,
	 * 将新策划书有效性置为1，并把新策划书下里程碑有效性全部置为1，同步新里程碑和旧里程碑的状态
	 * @Date 2021/12/02
	 **/
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void disableOldPlanAndMilePost(GpmProjectPlanEntity sdOldPlan, List<GpmProjectMilepostEntity> sdOldMilepostList,
										  GpmProjectPlanEntity sdNewPlan, List<GpmProjectMilepostEntity> sdNewMilepostList) {
		// 将旧策划书有效性置为0,将新策划书有效性置为1
		sdOldPlan.setEnabled(0);
		sdNewPlan.setEnabled(1);
		List<BasicEntity> sdProjectPlanEntities = new ArrayList<BasicEntity>();
		sdProjectPlanEntities.add(sdOldPlan);
		sdProjectPlanEntities.add(sdNewPlan);
		this.updateBatch(sdProjectPlanEntities);
		// 旧策划书下的里程碑有效性全部置为0
		Map<String,List<GpmProjectMilepostEntity>> sdOldMilePost = sdOldMilepostList.stream().collect
				(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.getOperatecode())));
		for(GpmProjectMilepostEntity sdProjectOldMilepostEntity: sdOldMilepostList) {
			sdProjectOldMilepostEntity.setEnabled(0);
		}
		// 新策划书下里程碑有效性全部置为1,同步新里程碑和旧里程碑的状态
		for(GpmProjectMilepostEntity sdProjectNewMilepostEntity: sdNewMilepostList) {
			sdProjectNewMilepostEntity.setEnabled(1);
			String newOperatecode = ConvertUtil.convertToString(sdProjectNewMilepostEntity.getOperatecode());
			// 如果新里程碑存在相同的旧里程碑，将旧里程碑的状态置给新里程碑
			if(sdOldMilePost.get(newOperatecode) != null && sdOldMilePost.get(newOperatecode).size() > 0) {
				int milepostState = sdOldMilePost.get(newOperatecode).get(0).getMilepoststate();
				sdProjectNewMilepostEntity.setMilepoststate(milepostState);
			}
		}
		List<BasicEntity> sdProjectMilePostEntities = new ArrayList<BasicEntity>();
		sdProjectMilePostEntities.addAll(sdOldMilepostList);
		sdProjectMilePostEntities.addAll(sdNewMilepostList);
		gpmProjectMilepostService.updateBatch(sdProjectMilePostEntities);
	}
	/**
	 * @return void
	 * @author houyuhang
	 * @Description 策划结束脚本-修改任务中里程碑名称
	 * @Date 2021/12/02
	 **/
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateTaskMilepostName(GpmProjectPlanEntity sdNewPlan, List<GpmProjectMilepostEntity> sdNewMilepostList) {
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" projectcode = '{0}' ",sdNewPlan.getProjectcode());
		List<GpmProjectTaskEntity> gpmProjectTaskEntityList = gpmProjectTaskService.queryByWhere(sql.toString());
		// 根据operatecode对新里程碑进行分类，一个operatecode对应一个里程碑
		Map<String,List<GpmProjectMilepostEntity>> sdNewMilePostMap = sdNewMilepostList.stream().collect
				(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.getOperatecode())));
		// 遍历任务，如果能找到该任务对应的里程碑，就对任务的里程碑名称进行更新
		for(GpmProjectTaskEntity gpmProjectTaskEntity : gpmProjectTaskEntityList) {
			String milepostCodeForTask = gpmProjectTaskEntity.getMilepostcode();
			if(sdNewMilePostMap.get(milepostCodeForTask) != null && sdNewMilePostMap.get(milepostCodeForTask).size() > 0) {
				String milepostname = sdNewMilePostMap.get(milepostCodeForTask).get(0).getMilepostname();
				gpmProjectTaskEntity.setMilepostname(milepostname);
			}
		}
		// 使用updateBatch更新任务的历程碑名称
		List<BasicEntity> updateEntity = new ArrayList<>();
		updateEntity.addAll(gpmProjectTaskEntityList);
		gpmProjectTaskService.updateBatch(updateEntity);
	}
	/**
	 * @return void
	 * @author houyuhang
	 * @Description 如果新里程碑改变了里程碑责任人，需要将任务反馈和任务关闭的里程碑责任人节点的办理人进行修改
	 * @Date 2021/12/03
	 **/
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateResponsibleCode(List<GpmProjectMilepostEntity> sdOldMilepostList, List<GpmProjectMilepostEntity> sdNewMilepostList) {
		// 旧里程碑按照operatecode进行分类
		Map<String,List<GpmProjectMilepostEntity>> sdOldMilepostMap = sdOldMilepostList.stream().
				collect(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.getOperatecode())));
		// 将里程碑责任人发生变化的新里程碑存入changeList
		List<GpmProjectMilepostEntity> changeList = new ArrayList<>();
		for(GpmProjectMilepostEntity gpmProjectMilepostEntity : sdNewMilepostList) {
			String operateCode = ConvertUtil.convertToString(gpmProjectMilepostEntity.getOperatecode());
			String responsibleCode = gpmProjectMilepostEntity.getResponsiblecode();
			if(sdOldMilepostMap.get(operateCode) != null && !responsibleCode.equals(sdOldMilepostMap.get(operateCode).get(0).getResponsiblecode())) {
				changeList.add(gpmProjectMilepostEntity);
			}
		}
		// 不存在里程碑责任人发生变化的情况
		if(changeList.size() == 0) {
			return;
		}
		// 存在里程碑责任人发生变化的情况
		List<BasicEntity> updateEntity = new ArrayList<>();
		StringBufferProxy sql = new StringBufferProxy();
		// 查询里程碑下处于里程碑责任人审批阶段的任务反馈和任务关闭流程
		String milepostId = changeList.stream().map(item -> ConvertUtil.convertToString(item.getId()))
				.collect(Collectors.joining("','","'","'"));
		// 任务反馈流程
		sql.appendSingle("GPMPROJECTMILEPOST.ID IN ({0}) and GPMPROJECTTASKFEEDBACK.STATE = 1 ",milepostId);
		List<Map<String,Object>> taskFeedbackApprovalList = gpmProjectMilepostService.queryMapByWhere(sql.toString(),"queryTaskFeedback");
		if(taskFeedbackApprovalList.size()>0) {
			for (Map<String, Object> taskFeedbackApprovalMap : taskFeedbackApprovalList) {
				// 查询人员code对应的id
				sql.clear();
				sql.appendSingle(" code = '{0}' ", ConvertUtil.convertToString(taskFeedbackApprovalMap.get("responsiblecode")));
				CboUserEntity cboUserEntity = cboUserService.queryObjectByWhere(sql.toString());
				// 查询里程碑责任人正在审批的流程
				sql.clear();
				sql.appendSingle("SELECT CBOAPPROVALNODEINS.* FROM CBOAPPROVALNODEINS INNER JOIN CBOAPPROVALNODE " +
						"ON CBOAPPROVALNODEINS.NODEID = CBOAPPROVALNODE.ID WHERE CBOAPPROVALNODEINS.SOURCEID = '{0}' " +
						"AND  CBOAPPROVALNODEINS.SOURCETYPE = '{1}' AND STATE = 1 AND " +
						"CBOAPPROVALNODE.APPROVALPARAM LIKE '%milepostcheckfeedback%'",taskFeedbackApprovalMap.get("sourceid"),
						GpmProjectTaskFeedbackEntity.tableName);
				List<Map<String,Object>> feedbackList = cboApprovalNodeInsService.selectExecute(sql.toString());
				// 存在任务反馈流程正处于里程碑责任人审批节点的流程，将里程碑责任人进行更换
				if(feedbackList.size() > 0) {
					CboApprovalNodeInsEntity cboApprovalNodeInsEntity = new CboApprovalNodeInsEntity();
					cboApprovalNodeInsEntity.convertFromMap(feedbackList.get(0));
					cboApprovalNodeInsEntity.setApprovaluserid(cboUserEntity.getId());
					updateEntity.add(cboApprovalNodeInsEntity);
				}
			}
		}
		// 任务关闭流程
		sql.clear();
		sql.appendSingle("GpmProjectMilepost.ID IN ({0}) and GpmPROJECTTASKCLOSE.STATE = 1 ",milepostId);
		List<Map<String,Object>> taskCloseApprovalList = gpmProjectMilepostService.queryMapByWhere(sql.toString(),"queryTaskClose");
		if(taskCloseApprovalList.size() > 0) {
			for (Map<String, Object> taskCloseApprovalMap : taskCloseApprovalList) {
				// 查询人员code对应的id
				sql.clear();
				sql.appendSingle(" code = '{0}' ", ConvertUtil.convertToString(taskCloseApprovalMap.get("responsiblecode")));
				CboUserEntity cboUserEntity = cboUserService.queryObjectByWhere(sql.toString());
				// 查询里程碑责任人正在审批的流程
				sql.clear();
				sql.appendSingle("SELECT CBOAPPROVALNODEINS.* FROM CBOAPPROVALNODEINS INNER JOIN CBOAPPROVALNODE " +
								"ON CBOAPPROVALNODEINS.NODEID = CBOAPPROVALNODE.ID WHERE CBOAPPROVALNODEINS.SOURCEID = '{0}' " +
								"AND  CBOAPPROVALNODEINS.SOURCETYPE = '{1}' AND STATE = 1 AND " +
								"CBOAPPROVALNODE.APPROVALPARAM LIKE '%milepostcheckclose%'",taskCloseApprovalMap.get("sourceid"),
						GpmProjectTaskCloseEntity.tableName);
				List<Map<String,Object>> closeList = cboApprovalNodeInsService.selectExecute(sql.toString());
				// 存在任务关闭流程正处于里程碑责任人审批节点的流程，将里程碑责任人进行更换
				if(closeList.size() > 0) {
					CboApprovalNodeInsEntity cboApprovalNodeInsEntity = new CboApprovalNodeInsEntity();
					cboApprovalNodeInsEntity.convertFromMap(closeList.get(0));
					cboApprovalNodeInsEntity.setApprovaluserid(cboUserEntity.getId());
					updateEntity.add(cboApprovalNodeInsEntity);
				}
			}
		}
		// 更新任务反馈和任务关闭的里程碑责任人节点办理人
		cboApprovalNodeInsService.updateBatch(updateEntity);
	}

	/**
	 * @return void
	 * @author zhangjunyao
	 * @Description 策划归档获取项目相关信息
	 * @Date 2021/12/14
	 **/
	public void getProjectInfo(List<Map<String, Object>> tempList) {
		String projectCodes = tempList.stream().map(map -> ConvertUtil.convertToString(map.get("projectcode")))
				.collect(Collectors.joining("','", "'", "'"));
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("projectcode in ({0})", projectCodes);
		List<GpmProjectEntity> projectEntities = gpmProjectService.queryByWhere(sql.toString());
		if (CollectionUtils.isEmpty(projectEntities)) {
			return;
		}
		Map<String, GpmProjectEntity> resultMap = projectEntities.stream().collect(Collectors.toMap(
				GpmProjectEntity::getProjectcode, sdProjectEntity -> sdProjectEntity));
		for (Map<String, Object> mapRow : tempList) {
			String projectCode = ConvertUtil.convertToString(mapRow.get("projectcode"));
			if (resultMap.containsKey(projectCode)) {
				GpmProjectEntity gpmProjectEntity = resultMap.get(projectCode);
				mapRow.put("projectname", gpmProjectEntity.getProjectname());
				mapRow.put("deptname", gpmProjectEntity.getDeptname());
				mapRow.put("target", gpmProjectEntity.getTarget());
				mapRow.put("projectmanager", gpmProjectEntity.getProjectmanager());
			}
		}
	}
	/**
	 * @return void
	 * @author houyuhang
	 * @Description 策划结束脚本更新任务的里程碑名称字段
	 * @Date 2022/04/02
	 **/
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMilepostNameForTask(GpmProjectMilepostEntity gpmProjectMilepostEntity) {
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" {0} = '{1}' ", GpmProjectTaskEntity.FieldMilepostcode, gpmProjectMilepostEntity.getOperatecode());
		List<GpmProjectTaskEntity> sdProjectTaskEntities = gpmProjectTaskService.queryByWhere(sql.toString());
		if(sdProjectTaskEntities.size() == 0) {
			return;
		}
		// 使用updateBatch更新任务的里程碑名称
		List<BasicEntity> updateEntity = new ArrayList<>();
		for(GpmProjectTaskEntity gpmProjectTaskEntity : sdProjectTaskEntities) {
			gpmProjectTaskEntity.setMilepostname(gpmProjectMilepostEntity.getMilepostname());
			updateEntity.add(gpmProjectTaskEntity);
		}
		gpmProjectTaskService.updateBatch(updateEntity);
	}
}
